package com.youlu.campus.service.file.impl;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.entity.FileExportTask;
import com.youlu.campus.entity.VO.req.FileExportTaskQueryVO;
import com.youlu.campus.service.file.FileExportTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class FileExportTaskServiceImpl implements FileExportTaskService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Page<FileExportTask> list(FileExportTaskQueryVO req) {
        log.info(":>>> 开始获取下载任务:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getUserId())) {
            log.error(":>>> 下载任务参数错误");
            throw new BusinessException("下载任务参数错误");
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getUserId())) {
            query.addCriteria(Criteria.where("optUserId").is(req.getUserId()));
        }
        if (StringUtils.isNotBlank(req.getBizType())) {
            query.addCriteria(Criteria.where("bizType").is(req.getBizType()));
        }
        if (StringUtils.isNotBlank(req.getFileName())) {
            query.addCriteria(Criteria.where("fileName").is(req.getFileName()));
        }
        long count = mongoTemplate.count(query, FileExportTask.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<FileExportTask> datas = mongoTemplate.find(query.with(pageRequest), FileExportTask.class);
        for (FileExportTask fileExportTask : datas) {
            fileExportTask.setToken("");
            fileExportTask.setUrl("");
        }
        return PageableExecutionUtils.getPage(datas, pageRequest, () -> count);
    }

    @Override
    public String downLoad(String id, String token) {
        log.info(":>>> 开始下载:{},{}", id, token);
        if (StringUtils.isBlank(id) || StringUtils.isBlank(token)) {
            log.error(":>>> 下载文件参数错误:id 或token为空");
            throw new BusinessException("下载文件参数错误:id 或token为空");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        FileExportTask f = mongoTemplate.findOne(query, FileExportTask.class);
        log.info(":>>> 下载地址:{}", f.getUrl());
        if (Objects.isNull(f)) {
            log.error(":>>> 文件不存在:{}", id);
            throw new BusinessException("文件不存在");
        }
        if (!token.equals(f.getOptUser())) {
            log.error(":>>> 用户token错误:{}", token);
            throw new BusinessException("用户token错误");
        }
        return f.getUrl();
    }

    @Override
    public String create(FileExportTask req) {
        log.info(":>>> 开始创建下载任务:{}", JSON.toJSONString(req));
        req.setId(null);
        req.setCreatedTime(new Date());
        req = mongoTemplate.insert(req);
        return req.getId();
    }

    @Override
    public void updateRunningNum(String id, Integer incr) {
        log.info(":>>> 开始更新执行中数量:{},{}", id, incr);
        if (Objects.isNull(id) || Objects.isNull(incr)) {
            log.error(":>>> 新执行中数量参数为空");
            return;
        }
        try {
            Query query = new Query().addCriteria(Criteria.where("id").is(id));
            Update update = new Update();
            update.inc("runningNum", incr);
            update.set("updatedTime", new Date());
            mongoTemplate.updateFirst(query, update, FileExportTask.class);
        } catch (Exception e) {
            log.error(":>>> 更新执行中数量错误:{}", e);
            return;
        }

    }

    @Async
    @Override
    public void updateExportNum(String id, Integer incr) {
        log.info(":>>> 开始更新导出中数量:{},{}", id, incr);
        if (Objects.isNull(id) || Objects.isNull(incr)) {
            log.error(":>>> 导出中数量参数为空");
            return;
        }
        try {
            Query query = new Query().addCriteria(Criteria.where("id").is(id));
            Update update = new Update();
            update.inc("exportedNum", incr);
            update.set("updatedTime", new Date());
            mongoTemplate.updateFirst(query, update, FileExportTask.class);

        } catch (Exception e) {
            log.error(":>>> 更新导出中数量错误:{}", e);
            return;
        }

    }

    @Override
    public void update(FileExportTask req) {
        log.info(":>>> 开始修改文件导出任务:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getId())) {
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        if(Objects.nonNull(req.getStatus()))
        update.set("status", req.getStatus());
        update.set("updatedTime", new Date());
        mongoTemplate.updateFirst(query, update, FileExportTask.class);

    }
}
